<?php

namespace app\admin\service;

use app\admin\cache\AdminCache;
use app\admin\enum\EnableStatus;
use app\admin\model\Admin;
use common\enum\ResultCode;
use Tinywan\ExceptionHandler\Exception\BadRequestHttpException;
use Tinywan\ExceptionHandler\Exception\NotFoundHttpException;
use Tinywan\ExceptionHandler\Exception\UnauthorizedHttpException;
use Tinywan\Jwt\Exception\JwtTokenException;
use Tinywan\Jwt\JwtToken;

class LoginService
{
    /**
     * 登录
     * @param string $username 管理员账号或手机号
     * @param string $password 密码
     * @return array|false
     */
    public function login(string $username, string $password): false | array
    {
        // 通过管理员账号或手机号查找管理员，并直接获取管理员的角色和菜单信息
        $admin = Admin::with([
            'roles' => function ($query) {
                $query->with([
                    'menus' => function ($query) {
                        $query->where('status', 1)->orderBy('sort', 'asc');
                    },
                ]);
            },
        ])->where(function ($query) use ($username) {
            $query->where('user_name', $username)->orWhere('mobile', $username);
        })->first();
        // 检查管理员是否存在
        if (!$admin) {
            throw new NotFoundHttpException(ResultCode::DATA_NOT_FOUND->getDescription());
        }
        // 检查管理员是否被禁用
        if ($admin->status == EnableStatus::DISABLED->value) {
            throw new BadRequestHttpException(ResultCode::USER_DISABLED->getDescription());
        }
        // 验证密码
        if (!password_verify($password, $admin->password)) {
            throw new BadRequestHttpException(ResultCode::PASSWORD_ERROR->getDescription());
        }
        // 更新最后登录时间和IP
        $admin->last_login_time = date('Y-m-d H:i:s');
        $admin->last_login_ip = request()->getRealIp();
        $admin->save();
        // 刷新管理员所有缓存
        AdminCache::refreshAllCache($admin);
        // 生成token
        return JwtToken::generateToken([
            'id' => $admin->id,
            'user_name' => $admin->user_name,
        ]);
    }

    /**
     * 退出登录
     * @return void
     */
    public function logout(): void
    {
        try {
            $admin = JwtToken::getExtend();
            AdminCache::clearAllCache($admin['id']);
            JwtToken::clear();
        } catch (JwtTokenException $exception) {
            throw new UnauthorizedHttpException($exception->getMessage());
        }
    }
}